/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.aice.chinamapview.component;

import com.aice.chinamapview.ResourceTable;
import com.aice.chinamapview.component.loading.LoadingView;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.AttrSet;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.ComponentContainer;
import ohos.agp.utils.Color;
import ohos.agp.utils.TextAlignment;
import ohos.app.Context;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.data.DatabaseHelper;
import ohos.data.preferences.Preferences;

/**
 * 加载Header
 *
 * @author czf
 * @since 2021-05-12
 */
public class ArrowRefreshHeader extends DirectionalLayout implements BaseRefreshHeader {
    private static final String XR_REFRESH_KEY = "XR_REFRESH_KEY";
    private static final String XR_REFRESH_TIME_KEY = "XR_REFRESH_TIME_KEY";
    private static final int SAVELASTREFRESHTIME = 200;
    private static final int HEIGHT = 400;
    private DirectionalLayout mContainer;
    private int mState = STATE_NORMAL;
    private int mMeasuredHeight;
    private final String customRefreshPsKey = null;
    private DirectionalLayout directionalLayout;
    private LoadingView loadingView;
    private Context mContext;

    /**
     * 构造方法
     *
     * @param context 上下文
     */
    public ArrowRefreshHeader(Context context) {
        this(context, null, null);
    }

    /**
     * 构造方法
     *
     * @param context 上下文
     * @param attrSet 线下像素
     */
    public ArrowRefreshHeader(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    /**
     * 构造方法
     *
     * @param context 上下文
     * @param attrSet 线下像素
     * @param styleName 定义样式属性
     */
    public ArrowRefreshHeader(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        initView(context);
    }

    private void initView(Context context) {
        this.mContext = context;
        LayoutScatter scatter = LayoutScatter.getInstance(context);
        mContainer = (DirectionalLayout) scatter.parse(ResourceTable.Layout_listview_header, null, false);

        LayoutConfig lp = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_CONTENT);
        lp.setMargins(0, 0, 0, 0);
        this.setPadding(0, 0, 0, 0);
        this.setLayoutConfig(lp);

        addComponent(mContainer, new LayoutConfig(LayoutConfig.MATCH_PARENT, 0));
        setAlignment(TextAlignment.BOTTOM);
        directionalLayout = (DirectionalLayout) mContainer.
                findComponentById(ResourceTable.Id_listview_header_backgroud);
        loadingView = (LoadingView)
                mContainer.findComponentById(ResourceTable.Id_progress_bar_loading);
        loadingView.setBindStateChangedListener(loadingView);
        loadingView.setPaintcolor(Color.getIntColor("#FF3E3D3D"));
        loadingView.stopAnimation();
        estimateSize(ComponentContainer.LayoutConfig.MATCH_CONTENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
        mMeasuredHeight = getEstimatedHeight();
    }

    /**
     * 设置状态
     *
     * @param state 状态值
     */
    public void setState(int state) {
        switch (state) {
            case STATE_NORMAL:
                mState = STATE_NORMAL;
                directionalLayout.setVisibility(VISIBLE);
                break;
            case STATE_RELEASE_TO_REFRESH:
                mState = STATE_RELEASE_TO_REFRESH;
                loadingView.stopAnimation();
                break;
            case STATE_REFRESHING:
                mState = STATE_REFRESHING;
                loadingView.startAnimation();
                break;
            case STATE_DONE:
                mState = STATE_NORMAL;
                directionalLayout.setVisibility(HIDE);
                break;
            default:
                break;
        }
    }

    public int getState() {
        return mState;
    }

    private void saveLastRefreshTime(long refreshTime) {
        String spKeyName = XR_REFRESH_KEY;
        if (customRefreshPsKey != null) {
            spKeyName = customRefreshPsKey;
        }
        DatabaseHelper databaseHelper = new DatabaseHelper(getContext());
        Preferences preferences = databaseHelper.getPreferences(spKeyName);
        preferences.putLong(XR_REFRESH_TIME_KEY, refreshTime).flush();
    }

    @Override
    public void refreshComplete() {
        saveLastRefreshTime(System.currentTimeMillis());
        setState(STATE_DONE);
        TaskDispatcher globalTaskDispatcher = mContext.getUITaskDispatcher();
        globalTaskDispatcher.delayDispatch(new Runnable() {
            @Override
            public void run() {
                reset();
            }
        }, SAVELASTREFRESHTIME);
    }

    /**
     * 设置高度
     *
     * @param height 状态值
     */
    public void setVisibleHeight(int height) {
        LayoutConfig lp = (LayoutConfig) mContainer.getLayoutConfig();
        if (height > HEIGHT) {
            lp.height = HEIGHT;
        } else {
            lp.height = height;
        }
        mContainer.setLayoutConfig(lp);
    }

    /**
     * 获取高度
     *
     * @return int height
     */
    public int getVisibleHeight() {
        LayoutConfig lp = (LayoutConfig) mContainer.getLayoutConfig();
        return lp.height;
    }

    @Override
    public void onMove(float delta) {
        if (getVisibleHeight() > 0 || delta > 0) {
            setVisibleHeight((int) delta + getVisibleHeight());
            if (mState <= STATE_RELEASE_TO_REFRESH) {
                // 未处于刷新状态，更新箭头
                if (getVisibleHeight() > mMeasuredHeight) {
                    setState(STATE_RELEASE_TO_REFRESH);
                } else {
                    setState(STATE_NORMAL);
                }
            }
        }
    }

    @Override
    public boolean releaseAction() {
        boolean isOnRefresh = false;
        mState = 1;
        if (getVisibleHeight() > mMeasuredHeight && mState < STATE_REFRESHING) {
            setState(STATE_REFRESHING);
            isOnRefresh = true;
        }
        if (mState != STATE_REFRESHING) {
            smoothScrollTo(0);
        }
        if (mState == STATE_REFRESHING) {
            int destHeight = mMeasuredHeight;
            setVisibleHeight(destHeight);
        }

        return isOnRefresh;
    }

    /**
     * 初始化高度
     *
     */
    public void reset() {
        smoothScrollTo(0);
    }

    private void smoothScrollTo(int destHeight) {
        loadingView.stopAnimation();
        setVisibleHeight(destHeight);
    }
}
